/*
 *	added by andrew morrison <morria@cs.rpi.edu> for building a webgraph
 * from web logs on the fly
 */

#include <assert.h>
#include <gr_graph_fun.h>
#include "LOGR_functions.h"
#include "LOGR_graph.h"

#define MAX_POSITION_ATTEMPTS 64

extern Node_type *select_nearest_vertex(struct pr_pos *loc, GraphFrame *gf);


struct pr_pos *get_next_node_pos(GraphFrame *graph) {
/*
 * return: a pr_pos struct. The goal is to give it a random
 *		unoccupied position
 */
	int i=0;
	int x = get_width(graph);
	int y = get_height(graph);
	struct pr_pos *loc = NULL;

	if(!(loc = (struct pr_pos *)malloc(sizeof(struct pr_pos)))) {
		perror("malloc()");
		exit(EXIT_FAILURE);
	}
	do {
		loc->x = (int)rand()%x;
		loc->y = (int)rand()%y;
	} while(select_nearest_vertex(loc,graph) != NULL && ++i<MAX_POSITION_ATTEMPTS);
	if(i == MAX_POSITION_ATTEMPTS) {
		fprintf(stderr,"Graph window too full, expanding size.\n");
		graph->w = x*2;
		graph->h = y*2;
		return get_next_node_pos(graph);
	}
	return loc;
}

PNODE add_new_node(GraphFrame *graph, char *label, int cur_size, int http_code) {
/*
 *	input:	current graph and name of label
 *	output:	pointer to new node if node does not exist, else a pointer to the existing node
 */

	PNODE curr = find_vertex_by_name(graph,label);

	if(!curr) {
		char size[32];
		char code[5];

		adding_vertex(graph,label,"1",get_next_node_pos(graph));
		curr = get_last_vertex(graph);
		
		snprintf(size,32,"%d",cur_size);
		snprintf(code,5,"%d",http_code);

		add_attribute(curr,"mime",HTGetMime(label));
		add_attribute(curr,"size",size);
		add_attribute(curr,"code",code);
		curr->counter = -1;
	}

	if(curr)
		++curr->counter;
	return curr;
}

PEDGE add_new_edge(GraphFrame *graph, PNODE from, PNODE to) {
/*
 *	output:	if nodes already connected by an edge that edge is returned, else an
 *		edge is created and returned.
 */
	PEDGE curr = find_edge(graph,from,to);
	if(!curr) {
		adding_edge(graph,from,to,"1");
		curr = find_edge(graph,from,to);
	}
	return curr;
}

void update_web_graph(
	GraphFrame *graph, /* must be at least initiated */
	char *cursite, /* may be NULL */
	char *curdate, /* may be NULL */
	int http_code,
	int cur_size,
	char *referer, /* may be NULL */
	char *curbrwoser, /* may be NULL if not given */
	char *curl, /* may be NULL */
	char *http_method,
	int nhttp_version /* dont worry about it */
	)
{
	PNODE cur_node = NULL;

	assert(graph != NULL);

	if(!curl)
		return;

	cur_node = add_new_node(graph, curl, cur_size, http_code);

	if(cur_node) {
		PNODE ref_node = NULL;
		if(referer && (ref_node = add_new_node(graph,referer, 0, 0))) {
			PEDGE edge = NULL;
			edge = add_new_edge(graph,ref_node,cur_node);
		}
	}
}
